using MediatR;
using S.O.Api.Write.Application.Command.Medical;
using S.O.Domain.Medical;
using S.O.ErrorCode;
using S.O.Interstructrue.Base;

namespace S.O.Api.Write.Application.Handler.Medical
{
    /// <summary>
    /// 医疗卡激活处理器
    /// 负责处理医疗卡的激活业务逻辑
    /// </summary>
    public class ActivateMedicalCardHandler : IRequestHandler<ActivateMedicalCardCommand, APIResult<bool>>
    {
        /// <summary>
        /// 医疗卡信息仓储
        /// </summary>
        private readonly IBaseRepository<MedicalCardModel> _medicalCardRepository;
        
        /// <summary>
        /// 日志记录器
        /// </summary>
        private readonly ILogger<ActivateMedicalCardHandler> _logger;

        /// <summary>
        /// 构造函数，通过依赖注入初始化所需服务
        /// </summary>
        /// <param name="medicalCardRepository">医疗卡信息仓储</param>
        /// <param name="logger">日志记录器</param>
        public ActivateMedicalCardHandler(
            IBaseRepository<MedicalCardModel> medicalCardRepository,
            ILogger<ActivateMedicalCardHandler> logger)
        {
            _medicalCardRepository = medicalCardRepository;
            _logger = logger;
        }

        /// <summary>
        /// 处理医疗卡激活命令
        /// </summary>
        /// <param name="request">医疗卡激活命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>激活结果</returns>
        public async Task<APIResult<bool>> Handle(ActivateMedicalCardCommand request, CancellationToken cancellationToken)
        {
            try
            {
                _logger.LogInformation($"开始处理医疗卡激活，卡号: {request.CardNo}, 患者: {request.PatientName}");
                
                // 验证输入参数
                var validationResult = ValidateRequest(request);
                if (!validationResult.IsValid)
                {
                    return new APIResult<bool>
                    {
                        Code = APIEnums.Error,
                        Data = false,
                        Msg = validationResult.ErrorMessage
                    };
                }
                
                // 查找医疗卡记录
                var medicalCard = _medicalCardRepository.GetALL()
                    .FirstOrDefault(c => c.CardNo == request.CardNo && !c.IsDeleted);
                    
                if (medicalCard == null)
                {
                    return new APIResult<bool>
                    {
                        Code = APIEnums.Error,
                        Data = false,
                        Msg = "医疗卡不存在"
                    };
                }
                
                // 验证医疗卡是否属于该患者
                if (medicalCard.PatientId != request.PatientId)
                {
                    return new APIResult<bool>
                    {
                        Code = APIEnums.Error,
                        Data = false,
                        Msg = "医疗卡不属于该患者"
                    };
                }
                
                // 验证患者身份信息
                if (medicalCard.PatientName != request.PatientName || medicalCard.IdCard != request.IdCard)
                {
                    return new APIResult<bool>
                    {
                        Code = APIEnums.Error,
                        Data = false,
                        Msg = "患者身份信息不匹配"
                    };
                }
                
                // 检查医疗卡当前状态
                if (medicalCard.CardStatus == "已激活")
                {
                    return new APIResult<bool>
                    {
                        Code = APIEnums.Error,
                        Data = false,
                        Msg = "该医疗卡已经激活，无需重复操作"
                    };
                }
                
                if (medicalCard.CardStatus == "已挂失")
                {
                    return new APIResult<bool>
                    {
                        Code = APIEnums.Error,
                        Data = false,
                        Msg = "该医疗卡已挂失，无法激活"
                    };
                }
                
                if (medicalCard.CardStatus == "已注销")
                {
                    return new APIResult<bool>
                    {
                        Code = APIEnums.Error,
                        Data = false,
                        Msg = "该医疗卡已注销，无法激活"
                    };
                }
                
                // 检查医疗卡是否过期
                if (medicalCard.ExpiryDate < DateTime.Now)
                {
                    return new APIResult<bool>
                    {
                        Code = APIEnums.Error,
                        Data = false,
                        Msg = "该医疗卡已过期，无法激活"
                    };
                }
                
                // 更新医疗卡状态为已激活
                medicalCard.CardStatus = "已激活";
                medicalCard.ActivateDate = DateTime.Now;
                
                // 更新备注信息
                var activateInfo = $"激活时间：{DateTime.Now:yyyy-MM-dd HH:mm:ss}，操作员：{request.Operator}，激活地点：{request.ActivateLocation}";
                if (!string.IsNullOrWhiteSpace(request.Remarks))
                {
                    activateInfo += $"，备注：{request.Remarks}";
                }
                
                medicalCard.Remarks = string.IsNullOrWhiteSpace(medicalCard.Remarks) 
                    ? activateInfo 
                    : $"{medicalCard.Remarks}；{activateInfo}";
                
                // 保存更新
                var result = _medicalCardRepository.Update(medicalCard);
                
                if (result > 0)
                {
                    _logger.LogInformation($"医疗卡激活成功，卡号: {request.CardNo}, 患者: {request.PatientName}");
                    return new APIResult<bool>
                    {
                        Code = APIEnums.Success,
                        Data = true,
                        Msg = "医疗卡激活成功"
                    };
                }
                else
                {
                    _logger.LogError($"医疗卡激活失败，数据库更新失败，卡号: {request.CardNo}");
                    return new APIResult<bool>
                    {
                        Code = APIEnums.Error,
                        Data = false,
                        Msg = "医疗卡激活失败，请稍后重试"
                    };
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"医疗卡激活时发生异常，卡号: {request.CardNo}");
                return new APIResult<bool>
                {
                    Code = APIEnums.Error,
                    Data = false,
                    Msg = "医疗卡激活失败，系统异常"
                };
            }
        }
        
        /// <summary>
        /// 验证请求参数
        /// </summary>
        /// <param name="request">请求参数</param>
        /// <returns>验证结果</returns>
        private (bool IsValid, string ErrorMessage) ValidateRequest(ActivateMedicalCardCommand request)
        {
            if (string.IsNullOrWhiteSpace(request.CardNo))
            {
                return (false, "医疗卡号不能为空");
            }
            
            if (request.PatientId <= 0)
            {
                return (false, "患者ID不能为空");
            }
            
            if (string.IsNullOrWhiteSpace(request.PatientName))
            {
                return (false, "患者姓名不能为空");
            }
            
            if (string.IsNullOrWhiteSpace(request.IdCard))
            {
                return (false, "身份证号不能为空");
            }
            
            if (!IsValidIdCard(request.IdCard))
            {
                return (false, "身份证号格式不正确");
            }
            
            return (true, string.Empty);
        }
        
        /// <summary>
        /// 验证身份证号格式
        /// </summary>
        /// <param name="idCard">身份证号</param>
        /// <returns>是否有效</returns>
        private bool IsValidIdCard(string idCard)
        {
            if (string.IsNullOrWhiteSpace(idCard))
                return false;
                
            // 简单的身份证号格式验证（15位或18位数字）
            return (idCard.Length == 15 || idCard.Length == 18) && 
                   idCard.All(c => char.IsDigit(c) || (idCard.Length == 18 && idCard[17] == 'X'));
        }
    }
}